package com.sniff.atp.service.order;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.sniff.atp.constant.LoginConstant;
import com.sniff.atp.dto.ClientLoginDTO;
import com.sniff.atp.dto.ContentDTO;
import com.sniff.atp.dto.SystemLoginDTO;
import com.sniff.atp.dto.WMSLoginDTO;
import com.sniff.atp.dto.wms.BatchDeliveryDeductionDto;
import com.sniff.atp.enums.api.OrderAPI;
import com.sniff.atp.enums.sql.SniffSql;
import com.sniff.atp.enums.status.OrderFlowType;
import com.sniff.atp.service.purchase.OEMPurchaseService;
import com.sniff.atp.service.purchase.PurchaseService;
import com.sniff.atp.service.settlement.SettlementService;
import com.sniff.atp.service.wms.stock.WmsStockOutService;
import com.sniff.atp.service.wms.storage.WMSCombinationOperationService;
import com.sniff.atp.service.wms.storage.WMSStorageService;
import com.sniff.atp.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.testng.Assert;
import java.math.BigDecimal;
import java.util.*;

@Service
public class OrderService {
    @Autowired
    private PurchaseAllotOrder purchaseAllotOrder;
    @Autowired
    private PurchaseService purchaseService;
    @Autowired
    private OEMPurchaseService oemPurchaseService;
    @Autowired
    private WMSStorageService wmsStorageService;
    @Autowired
    private WMSCombinationOperationService wmsCombinationOperationService;
    @Autowired
    private WmsStockOutService wmsStockOutService;
    @Autowired
    private SettlementService settlementService;
    @Autowired
    private OEMOrderService oemOrderService;
    private Logger logger = LoggerFactory.getLogger(WmsStockOutService.class);

    public String clientAddCart(ClientLoginDTO clientLoginDTO, Object combinationGoods) {
        // 组合商品加购
        return new HttpClientUtil(Headers.setClientHeader(clientLoginDTO))
                .doPostJson(OrderAPI.COM_AddCart.getApi(), combinationGoods);
    }

    public String clientCartQuantity(ClientLoginDTO clientLoginDTO, String cartId, Integer num) {
        JSONObject params = JsonUtil.readJson("order/cart/CartQuantity");
        params.put("cartId", cartId);
        params.put("orderQuantity", num);
        return new HttpClientUtil(Headers.setClientHeader(clientLoginDTO))
                .doPostJson(OrderAPI.CART_QUANTITY.getApi(), params);
    }

    public String clientCartList(ClientLoginDTO clientLoginDTO) {
        // 获取购物车列表
        return new HttpClientUtil(Headers.setClientHeader(clientLoginDTO))
                .doGetURL(OrderAPI.CART_LIST.getApi());
    }

    public String clientOrderList(ClientLoginDTO clientLoginDTO, String platformOrderNo) {
        JSONObject params = JsonUtil.readJson("ClientOrderList", new ContentDTO("platformOrderNo", platformOrderNo));
        params.put("customerShopId", clientLoginDTO.getShopId());
        return new HttpClientUtil(Headers.setClientHeader(clientLoginDTO))
                .doPostJson(OrderAPI.CLIENT_ORDER_LIST.getApi(), params);
    }

    public String clientOrderDetail(ClientLoginDTO clientLoginDTO, String platformOrderNo) {
        String clientOrderList = clientOrderList(clientLoginDTO, platformOrderNo);
        String platformOrderId = JsonUtil.extractString(clientOrderList, "data.records[0].platformOrderId");
        // 增加等待组合商品获取时间
        ToolsUtil.sleep(5000);
        Map<String, String> params = new HashMap<>();
        params.put("platformOrderId", platformOrderId);
        return new HttpClientUtil(Headers.setClientHeader(clientLoginDTO))
                .doGet(OrderAPI.ORDER_DETAIL.getApi(), params);
    }

    public String clientOrderDetailAssert(ClientLoginDTO clientLoginDTO, String platformOrderNo, OrderFlowType orderFlowType) {
        String orderDetail = clientOrderDetail(clientLoginDTO, platformOrderNo);
        BigDecimal orderPrice = JsonUtil.sumPriceOrder(JsonUtil.extractJSONArray(orderDetail, "data.platformOrderItemList"));
        Assert.assertNotNull(orderPrice);
        // 出入账校验
        String fundFlow = settlementService.queryFundFlow(clientLoginDTO, platformOrderNo);
        JSONObject changeAmount = JsonUtil.findJSONArray(JsonUtil.extractJSONArray(fundFlow, "data.records"), "fundFlowType", String.valueOf(orderFlowType.getFundFlowType()));
        Assert.assertEquals(orderPrice, changeAmount == null ? new BigDecimal("0.00") : changeAmount.getBigDecimal("changeAmount"));
        JSONObject orderObject = JSON.parseObject(orderDetail);
        orderObject.put("orderPrice", orderPrice);
        return orderObject.toJSONString();
    }

    public String getCurrentCartList(ClientLoginDTO clientLoginDTO) {
        return new HttpClientUtil(Headers.setClientHeader(clientLoginDTO))
                .doGetURL(OrderAPI.CURRENT_CART_LIST.getApi());
    }

    /**
     * productType: 2(OEM)
     */
    public String clientGetMyInventory(ClientLoginDTO clientLoginDTO, String productSkuOrName, String productType) {
        JSONObject params = JsonUtil.readJson("order/ProductMyInventory", new ContentDTO("productSkuOrName", productSkuOrName));
        params.put("productType", productType);
        return new HttpClientUtil(Headers.setClientHeader(clientLoginDTO))
                .doPostJson(OrderAPI.PRODUCT_MY_INVENTORY.getApi(), params);
    }

    public String cartList(ClientLoginDTO clientLoginDTO) {
        return new HttpClientUtil(Headers.setClientHeader(clientLoginDTO))
                .doGetURL(OrderAPI.CART_LIST.getApi());
    }

    /**
     * 购物车直发
     */
    public String clientDeliverCreateOrder(ClientLoginDTO clientLoginDTO, String cartId) {
        // 获取购物车列表
        String cartList = cartList(clientLoginDTO);
        // 获取当前加购的商品信息
        JSONObject cartDetail = JsonUtil.findJSONArray(JsonUtil.extractJSONArray(cartList, "data"), "cartList.cartId", cartId);
        Assert.assertNotNull(cartDetail);
        // 创建订单
        JSONObject params = JsonUtil.readJson("order/createOrder");
        params.put("cartIdList", Collections.singletonList(cartId));
        String createOrder = new HttpClientUtil(Headers.setClientHeader(clientLoginDTO))
                .doPostJson(OrderAPI.CREATE_ORDER.getApi(), params);
        String platformOrderNo = JsonUtil.extractString(createOrder, "data.platformOrderNo");
        String platformOrderId = JsonUtil.extractString(createOrder, "data.platformOrderId");
        String orderDetail = clientOrderDetailAssert(clientLoginDTO, platformOrderNo, OrderFlowType.fund_flow_type_eight);
        JSONObject orderItem = JsonUtil.findJSONArray(JsonUtil.extractJSONArray(orderDetail, "data.platformOrderItemList"), "platformOrderId", platformOrderId);
        Assert.assertEquals(cartDetail.getBigDecimal("orderQuantity"), orderItem.getBigDecimal("orderQuantity"));
        return orderDetail;
    }

    /**
     * 购物车囤货
     */
    public String clientStockUpCreateOrderByProduct(ClientLoginDTO clientLoginDTO, String productSKu) {
        String cartId = oemOrderService.oemAddCart(clientLoginDTO, productSKu);
        return clientStockUpCreateOrder(clientLoginDTO, cartId);
    }

    /**
     * 购物车直发
     */
    public String clientDeliveryCreateOrderByProduct(ClientLoginDTO clientLoginDTO, String productSKu) {
        String cartId = oemOrderService.oemAddCart(clientLoginDTO, productSKu);
        return clientDeliverCreateOrder(clientLoginDTO, cartId);
    }

    /**
     * 创建组合商品加入购物车-囤货
     */
    public String clientStockUpCombAddCart(ClientLoginDTO clientLoginDTO) {
        JSONObject params = JsonUtil.readJson("order/cart/CombCreateAndAddCart.json");
        params.put("combinationProductName", "COMB-NAME-AUTO-" + RandomUtil.numberString(5));
        params.put("combinationProductProp", "COMB-PROP-AUTO-" + RandomUtil.numberString(5));
        return new HttpClientUtil(Headers.setClientHeader(clientLoginDTO)).doPostJson(OrderAPI.COMB_CREATE_AND_CART.getApi(), params);
    }

    public String clientStockUpCreateOrder(ClientLoginDTO clientLoginDTO, List<String> cartIds) {
        return new HttpClientUtil(Headers.setClientHeader(clientLoginDTO))
                .doPostJson(OrderAPI.CREATE_ORDER.getApi(), JsonUtil.readJson("StockUpCreateOrder", new ContentDTO("cartIds", cartIds.toString())));
    }

    public String clientStockUpCreateOrder(ClientLoginDTO clientLoginDTO, String cartId) {
        // 获取当前加购的商品信息
        JSONObject cartDetail = JsonUtil.findJSONArray(JsonUtil.extractJSONArray(clientCartList(clientLoginDTO), "data"), "cartList.cartId", cartId);
        Assert.assertNotNull(cartDetail);
        // 创建订单
        String createOrder = clientStockUpCreateOrder(clientLoginDTO, Collections.singletonList(cartId));
        String platformOrderNo = JsonUtil.extractString(createOrder, "data.platformOrderNo");
        return clientOrderDetailAssert(clientLoginDTO, platformOrderNo, OrderFlowType.fund_flow_type_eight);
    }

    public String systemOrderList(SystemLoginDTO systemLoginDTO, String platformOrderNo) {
        return new HttpClientUtil(Headers.setSystemHeader(systemLoginDTO))
                .doPostJson(OrderAPI.ORDER_LIST.getApi(), JsonUtil.readJson("OrderPlatFormOrder", new ContentDTO("platformOrderNo", platformOrderNo)));
    }

    public JSONObject orderProcess(String platformOrderNo, Integer operationNode) {
        JSONObject stringObjectHashMap = new JSONObject();

        SystemLoginDTO systemLoginDTO = LoginConstant.systemLoginDTO;

        //根据订单切换仓库
        List<JSONObject> sniffPlatformOrder = DBUtil.select(SniffSql.SQL008.getAlias(), new ContentDTO("", platformOrderNo));
        String wareCode = sniffPlatformOrder.get(0).getString("ware_code");
        wmsStorageService.switchHouse(LoginConstant.wmsLoginDTO, wareCode);
        WMSLoginDTO wmsLoginDTO = LoginConstant.wmsLoginDTO;

        if (operationNode == null || operationNode == 0 || operationNode == 1) {
            return stringObjectHashMap;
        }

        //分单
        ToolsUtil.sleep(5000);
        String s = purchaseService.allotAutoOrder(systemLoginDTO, platformOrderNo);
        //返回分单结果
        stringObjectHashMap.put("platformOrderNo", platformOrderNo);
        stringObjectHashMap.put("operationNode", "分单完成");
        JSONObject jsonObject = JsonUtil.strToJSONObject(s);
        stringObjectHashMap.put("allotPurchaseOrder", jsonObject.getJSONArray("data"));

        if(2 == operationNode) {
            return stringObjectHashMap;
        }

        //获取所有采购单
        List<JSONObject> purchaseList = purchaseAllotOrder.getPurchaseOrderInfo(platformOrderNo);
        // 执行采购和入库
        JSONArray purchaseInfos = new JSONArray();
        if (!purchaseList.isEmpty()) {
            //执行采购
            for (JSONObject ob : purchaseList) {
                JSONObject purchaseInfo = new JSONObject();
                String purchaseNo = ob.getString("purchase_no");
                String purchaseStatus = ob.getString("purchase_status");
                purchaseInfo.put("purchaseOrderNo", purchaseNo);
                if (purchaseNo.contains("DHCGD") || purchaseNo.contains("YPCGD")) {
                    if ("0".equals(purchaseStatus)) {
                        oemPurchaseService.oemPurchaseProcess(systemLoginDTO, purchaseNo);
                        Object logisticsNumber = ToolsUtil.getStringBuild("oemLogisticsNumber");
                        purchaseInfo.put("logisticsNumber", logisticsNumber);
                    }
                }else {
                    purchaseService.puchasePrecess(systemLoginDTO, purchaseNo);
                    purchaseService.setPurchaseToken(systemLoginDTO);
                    String res = purchaseService.listPurchase(purchaseNo);
                    String logisticsNumber = JsonUtil.extractString(res, "data.records[0].logisticsNumberList[0].logisticsNumber");
                    purchaseInfo.put("logisticsNumber", logisticsNumber);
                }
                purchaseInfos.add(purchaseInfo);
            }

            //返回采购结果
            stringObjectHashMap.put("purchaseData", purchaseInfos);
            stringObjectHashMap.put("operationNode", "采购完成");

            if (operationNode == 3) {
                return stringObjectHashMap;
            }

            // 执行入库
            ToolsUtil.sleep(2000);
            JSONArray inboundData = wmsStorageService.storageProcess(wmsLoginDTO, platformOrderNo);

            //返回入库结果
            stringObjectHashMap.put("inboundData", inboundData);
            stringObjectHashMap.put("operationNode", "入库完成");

            if (operationNode == 4) {
                return stringObjectHashMap;
            }
        }

        // 组合商品执行组合完成
        boolean isCombination = wmsCombinationOperationService.platformOrderCombinationProcess(wmsLoginDTO, platformOrderNo);
        if (isCombination) {
            //返回组合结果
            stringObjectHashMap.put("operationNode", "组合完成");
        }

        if (operationNode == 5) {
            return stringObjectHashMap;
        }

        //审单完成
        boolean reviewResult = wmsStockOutService.singleReview(wmsLoginDTO,platformOrderNo);
        if (!reviewResult) {
            stringObjectHashMap.put("operationNode", "审单失败");
            return stringObjectHashMap;
        }
        stringObjectHashMap.put("operationNode", "审单完成");
        if (operationNode == 6) {
            return stringObjectHashMap;
        }

        //国际发货单抵扣
        String deliveryTaskCode = null;
        Integer deliveryStatus;
        for(int i=1 ;i<=25;i++) {
            logger.info("循环第几次:{}", i);
            //通过sql查询发货单
            JSONObject object = DBUtil.selectOne("WMS-根据发货单号或平台订单号查寻发货单", new ContentDTO("", platformOrderNo));
            deliveryTaskCode = object.getString("delivery_task_code");
            deliveryStatus = object.getInteger("delivery_status");
            Long customerShopId = object.getLong("customer_shop_id");

            if (deliveryTaskCode == null || StringUtils.isEmpty(deliveryTaskCode) || "null".equals(deliveryTaskCode)) {
                stringObjectHashMap.put("operationNode", "订单未创建国际发货单");
                return stringObjectHashMap;
            }
            logger.info("deliveryTaskCode:{}", deliveryTaskCode);
            if (deliveryStatus > -1) {
                break;
            }
            //首次循环
            if(deliveryStatus == -1 && i == 1) {
                //触发国际发货单抵扣
                List<String> deliveryTaskCodeList = new ArrayList<>(Collections.singletonList(deliveryTaskCode));
                BatchDeliveryDeductionDto batchDeliveryDeductionDto = new BatchDeliveryDeductionDto();
                batchDeliveryDeductionDto.setCustomerShopId(customerShopId);
                batchDeliveryDeductionDto.setDeliveryTaskCodeList(deliveryTaskCodeList);
                wmsStockOutService.batchDeliveryTaskDeduction(wmsLoginDTO, batchDeliveryDeductionDto);

                //校验是否有在途库存未抵扣
                List<JSONObject> wmsDeliveryTaskDetail = wmsStockOutService.getTransitPartialDeduction(deliveryTaskCode);
                if(wmsDeliveryTaskDetail.size() > 0){
                    stringObjectHashMap.put("operationNode", "在途未全部抵扣，请完成在途抵扣后重试！");
                    return stringObjectHashMap;
                }
            }

            if(i == 25){
                stringObjectHashMap.put("operationNode", "国际发货单抵扣失败");
                return stringObjectHashMap;
            }

            //等待3秒
            ToolsUtil.sleep(3000);
        }

        //返回待处理状态
        stringObjectHashMap.put("operationNode", "国际发货单待处理");
        stringObjectHashMap.put("deliveryTaskCode", deliveryTaskCode);
        //国际发货单抵扣完成
        if (operationNode == 7) {
            return stringObjectHashMap;
        }

        //DB插入国际物流单号
        wmsStockOutService.addLogisticsNo(deliveryTaskCode);
        //拣货、分拣完成
        JSONObject pickInfo = wmsStockOutService.toPickedProcess(wmsLoginDTO,deliveryTaskCode);
        //返回拣货、分拣信息
        stringObjectHashMap.put("pickInfo", pickInfo);
        stringObjectHashMap.put("operationNode", "拣货分拣完成");

        if (operationNode == 8) {
            return stringObjectHashMap;
        }
        //打包完成
        wmsStockOutService.packing(wmsLoginDTO, 2, deliveryTaskCode);
        stringObjectHashMap.put("operationNode", "打包完成");
        if (operationNode == 9) {
            return stringObjectHashMap;
        }
        //确认发货
        wmsStockOutService.confirmStock(wmsLoginDTO,deliveryTaskCode);

        //获取国际发货单列表
        JSONArray wmsDeliveryTaskInfo = wmsStockOutService.getWmsDeliveryTaskInfo(platformOrderNo);
        stringObjectHashMap.put("wmsDeliveryTaskInfo", wmsDeliveryTaskInfo);
        stringObjectHashMap.put("operationNode", "发货完成");

        return stringObjectHashMap;
    }
}
